﻿using HelixToolkit.Wpf;
using Microsoft.Win32;
using System.Collections.ObjectModel;
using System.IO;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Media.Media3D;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;
using Brushes = System.Windows.Media.Brushes;
using MessageBox = System.Windows.MessageBox;
using Path = System.IO.Path;

namespace TeaStlShow
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public DispatcherTimer Timer = new DispatcherTimer();
        private TeathCuttingData CurrentTeathCuttingData;
        public List<TeathCuttingData> AllTeathData = new List<TeathCuttingData>();
        ObservableCollection<string> CodeList = new ObservableCollection<string>();
        List<BillboardTextVisual3D> AllPointNumber = new List<BillboardTextVisual3D>();
        private ModelVisual3D stlModel;
        private PointsVisual3D pointCloud;
        private LinesVisual3D normalLinesF;
        private LinesVisual3D normalLinesX;
        private LinesVisual3D normalLinesY;


        public MainWindow()
        {
            InitializeComponent();
            // 设置时间间隔，比如1秒
            Timer.Interval = TimeSpan.FromMilliseconds(300);
            // 绑定Tick事件
            Timer.Tick += Timer_Tick;
            // 启动定时器
            Timer.Start();
            CodeGrid.ItemsSource = CodeList;
        }

        private void Timer_Tick(object? sender, EventArgs e)
        {
         
        }

        private void ImportSTL_Click(object sender, RoutedEventArgs e)
        {
            if (CurrentTeathCuttingData.stlModelYuan!=null)
            {
                if (stlModel != null)
                    viewport3D.Children.Remove(stlModel);
                if (chkShowStl.IsChecked ?? true)
                {
                    stlModel = new ModelVisual3D { Content = CurrentTeathCuttingData.stlModelYuan };
                    viewport3D.Children.Add(stlModel);
                }
            }
            else
            {
                MessageBox.Show("STL模型导入失败");
            }
        }
        private void ImportPTS_Click(object sender, RoutedEventArgs e)
        {
            if (CurrentTeathCuttingData.pointCloudYuan.Count > 0)
            {
                UpdateVisualization();
            }
            else
            {
                MessageBox.Show("PTS点云导入失败！");
            }
        }

        private void UpdateVisualization()
        {
            // 移除现有的点云和法向显示
            if (pointCloud != null)
                viewport3D.Children.Remove(pointCloud);
            if (normalLinesF != null)
                viewport3D.Children.Remove(normalLinesF);
            if (normalLinesX != null)
                viewport3D.Children.Remove(normalLinesX);
            if (normalLinesY != null)
                viewport3D.Children.Remove(normalLinesY);
            if (AllPointNumber.Count > 0)
            {
                foreach (var tv in AllPointNumber)
                {
                    viewport3D.Children.Remove(tv);
                }
            }
              // 清空列表
               AllPointNumber.Clear();

            if (CurrentTeathCuttingData.pointCloudYuan != null && CurrentTeathCuttingData.pointCloudYuan.Count > 0)
            {
                // 显示点云
                if (chkShowPoints.IsChecked == true)
                {
                    pointCloud = new PointsVisual3D
                    {
                        Points =new Point3DCollection(CurrentTeathCuttingData.pointCloudYuan),
                        Color = Colors.Red,
                        Size = 10
                    };
                    viewport3D.Children.Add(pointCloud);
                }

                // 显示法向
                if (chkShowNormals.IsChecked == true)
                {
                    normalLinesF = new LinesVisual3D();
                    normalLinesX = new LinesVisual3D();
                    normalLinesY = new LinesVisual3D();
                    for (int i = 0; i < CurrentTeathCuttingData.SortpointCloudYuan.Count; i++)
                    {
                        var Zstart = CurrentTeathCuttingData.SortpointCloudYuan[i];
                        Vector3D znormaleone = CurrentTeathCuttingData.normalLinesFZ[i];
                        znormaleone.Normalize();
                        var Zend = Zstart + znormaleone * 2; // 法向长度缩放

                        normalLinesF.Points.Add(Zstart);
                        normalLinesF.Points.Add(Zend);

                        var Xstart = CurrentTeathCuttingData.SortpointCloudYuan[i];
                        var Xnormal = CurrentTeathCuttingData.normalLinesFX[i];
                        Xnormal.Normalize();    
                        var Xend = Xstart + Xnormal * 2;
                        normalLinesX.Points.Add(Xstart);
                        normalLinesX.Points.Add(Xend);

                        var Ystart = CurrentTeathCuttingData.SortpointCloudYuan[i];
                        var Ynormal = CurrentTeathCuttingData.normalLinesFY[i];

                        Ynormal.Normalize();
                        var Yend= Ystart + Ynormal * 2;
                        normalLinesY.Points.Add(Ystart);
                        normalLinesY.Points.Add(Yend);

                      
                        var textVisual = new BillboardTextVisual3D();
                        textVisual.Text = i.ToString(); // 设置文本内容
                        textVisual.Position = Zstart - znormaleone * 5; // 设置文本位置，x, y, z为点云点的坐标
                        textVisual.FontSize = 16; // 设置字体大小
                        textVisual.Foreground = Brushes.LightPink; // 设置字体颜色
                        // 将文本添加到视图中
                        viewport3D.Children.Add(textVisual);
                        AllPointNumber.Add(textVisual);
                    }
                    normalLinesF.Color = Colors.Blue;
                    normalLinesF.Thickness = 2;
                    viewport3D.Children.Add(normalLinesF);
                    normalLinesX.Color = Colors.Red;
                    normalLinesX.Thickness = 2;
                    viewport3D.Children.Add(normalLinesX);
                    normalLinesY.Color = Colors.Green;
                    normalLinesY.Thickness = 2;
                    viewport3D.Children.Add(normalLinesY);
                }
            }
        }
        public void DrawCircle(HelixViewport3D viewport, Point3D center, double radius, int segments)
        {
            var circle = new LinesVisual3D
            {
                Color = Colors.Red,
                Thickness = 2
            };

            for (int i = 0; i < segments; i++)
            {
                double theta1 = 2 * Math.PI * i / segments;
                double theta2 = 2 * Math.PI * (i + 1) / segments;

                var p1 = new Point3D(
                    center.X + radius * Math.Cos(theta1),
                    center.Y + radius * Math.Sin(theta1),
                    center.Z);

                var p2 = new Point3D(
                    center.X + radius * Math.Cos(theta2),
                    center.Y + radius * Math.Sin(theta2),
                    center.Z);

                circle.Points.Add(p1);
                circle.Points.Add(p2);
            }
            viewport.Children.Add(circle);
        }
        /// <summary>
        /// 生成运动路径
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void GeneratePath_Click(object sender, RoutedEventArgs e)
        {
            if (Directory.Exists(OutDirText.Text))
            {
                CurrentTeathCuttingData.ExcuteToFile(OutDirText.Text);
            }
            else
            {
                MessageBox.Show("输出后处理的文件夹不存在,请选择输出的文件夹");
            }
        }

        private void SelectDirectory_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                using (var folderDialog = new FolderBrowserDialog())
                {
                    folderDialog.Description = "请选择文件夹";
                    folderDialog.ShowNewFolderButton = true;

                    if (folderDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                    {
                        TextDirectory.Text = folderDialog.SelectedPath;
                    }
                }
            }
            catch (Exception ex)
            {
                System.Windows.MessageBox.Show($"打开文件夹对话框时出错: {ex.Message}", "错误",
                    MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }

        private void CurrentCode_Click(object sender, RoutedEventArgs e)
        {

        }

        private void SetCurrentCode_Click(object sender, RoutedEventArgs e)
        {

        }

        private void ShowStlPts_Click(object sender, RoutedEventArgs e)
        {
            string code = TextCode.Text;
            for (int i = 0; i < AllTeathData.Count; i++)
            {
                if (AllTeathData[i].Code == code)
                {
                    CurrentTeathCuttingData = AllTeathData[i];
                    ImportSTL_Click(sender,e);
                    ImportPTS_Click(sender,e);
                }
            }
        }

        private void LoadData_Click(object sender, RoutedEventArgs e)
        {
            CurrentTeathCuttingData = null;
            AllTeathData.Clear();
            CodeList.Clear();
            string directory=TextDirectory.Text;
            try
            {
                if (Directory.Exists(directory))
                {
                    string[] stlfiles = Directory.GetFiles(directory, "*.stl").Select(path => Path.GetFileNameWithoutExtension(path)).ToArray();;
                    string[] ptsfiles = Directory.GetFiles(directory, "*.pts").Select(path => Path.GetFileNameWithoutExtension(path)).ToArray(); ;
                    if (stlfiles.Length == ptsfiles.Length)
                    {
                        object lockObj = new object();
                        TeathCuttingData.StlDirectory = directory;
                        for (int i = 0; i < stlfiles.Length; i++)
                        {
                            string filepath = stlfiles[i];
                            TeathCuttingData oneteath = new TeathCuttingData();
                            oneteath.Init();
                            Task.Run(() =>
                            {
                                if (oneteath.SetCode(filepath))
                                {
                                    lock (lockObj)
                                    {
                                        AllTeathData.Add(oneteath);
                                        System.Windows.Application.Current.Dispatcher.Invoke(() =>
                                        {
                                            CodeList.Add(oneteath.Code);
                                        });
                                    }
                                }
                            });
                        }
                    }
                    else
                    { //查找下那个stl和pts缺失
                        List<string> ptsfilelist = ptsfiles.ToList<string>();
                        for (int i = 0; i < stlfiles.Length; i++)
                        {
                            if (ptsfilelist.Contains(stlfiles[i]))
                            {
                                ptsfilelist.RemoveAt(i);
                            }
                            else
                            {
                                MessageBox.Show($"有STL没有pts:{stlfiles[i]}");
                            }
                        }
                        for (int i = 0; i < ptsfilelist.Count; i++)
                        {
                            MessageBox.Show($"有PTS没有STL:{ptsfilelist[i]}");
                        }
                    }
                }
            }
            catch (Exception)
            {
                throw;
            }

        }

        private void CodeGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (CodeGrid.SelectedItem is string selectedCode)
            {
                TextCode.Text = selectedCode;
                ShowStlPts_Click(sender, e);
            }
        
        }

        private void OutDataDir_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                using (var folderDialog = new FolderBrowserDialog())
                {
                    folderDialog.Description = "请选择文件夹";
                    folderDialog.ShowNewFolderButton = true;

                    if (folderDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                    {
                        OutDirText.Text = folderDialog.SelectedPath;
                    }
                }
            }
            catch (Exception ex)
            {
                System.Windows.MessageBox.Show($"打开文件夹对话框时出错: {ex.Message}", "错误",
                    MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }

        private void chkShowStl_Checked(object sender, RoutedEventArgs e)
        {
            ShowStlPts_Click(sender,e);
        }

        private void chkShowPoints_Checked(object sender, RoutedEventArgs e)
        {
            ShowStlPts_Click(sender, e);
        }

        private void chkShowNormals_Checked(object sender, RoutedEventArgs e)
        {
            ShowStlPts_Click(sender, e);
        }

        private void Window_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            LargeStatic.MaxWidth = this.Height;
        }

        private void CreateAllPath_Click(object sender, RoutedEventArgs e)
        {
            if (Directory.Exists(OutDirText.Text))
            {
                for (int i = 0; i < AllTeathData.Count; i++)
                {
                    AllTeathData[i].ExcuteToFile(OutDirText.Text);
                }
            }
            else
            {
                MessageBox.Show("输出后处理的文件夹不存在,请选择输出的文件夹");
            }
        }

        private void chkShowStl_Unchecked(object sender, RoutedEventArgs e)
        {
            ShowStlPts_Click(sender, e);
        }

        private void chkShowPoints_Unchecked(object sender, RoutedEventArgs e)
        {
            ShowStlPts_Click(sender, e);
        }

        private void chkShowNormals_Unchecked(object sender, RoutedEventArgs e)
        {
            ShowStlPts_Click(sender, e);
        }
    }
}